﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;
using UnityEngine;

public class BinaryReaderTool : BaseObject
{
    private bool Is_Little_Endian = BitConverter.IsLittleEndian;

    private static BinaryReaderTool self;

    private string BIN_FILE_NAME = Application.dataPath + "/res/CN.bin";

    private bool isLoaded = false;

    public BinaryReaderTool() { }

    public static BinaryReaderTool getInstance()
    {
        if (self == null)
        {
            self = new BinaryReaderTool();
        }
        return self;
    }

    /// <summary>
    /// 读取文本到内存调用
    /// </summary>
    /// <param name="path">文本路径</param>
    public void LoadString()
    {
        if (isLoaded) return;
        FileStream fs = null;
        BinaryReader br = null;
        try
        {
            // 首先判断，文件是否已经存在
            if (!File.Exists(BIN_FILE_NAME))
            {
                // 如果文件不存在，那么提示无法读取！
                Console.WriteLine("二进制文件{0}不存在！", BIN_FILE_NAME);
                return;
            }


            fs = new FileStream(BIN_FILE_NAME, FileMode.Open, FileAccess.Read);
            br = new BinaryReader(fs, Encoding.ASCII);

            if(br.PeekChar() != -1)
            {
                byte[] txtLengthArr = br.ReadBytes(4);
                ChangeByteTurn(txtLengthArr);
                int txtLength = BitConverter.ToInt32(txtLengthArr,0);

                for (int i = 0; i < txtLength; i++)
                {
                    byte[] serverKeyArr = br.ReadBytes(4);
                    ChangeByteTurn(serverKeyArr);
                    int serverKey = BitConverter.ToInt32(serverKeyArr, 0);

                    byte[] designLengthArr = br.ReadBytes(2);
                    ChangeByteTurn(designLengthArr);
                    int designLength = BitConverter.ToInt16(designLengthArr, 0);
                    byte[] designKeyArr = br.ReadBytes(designLength);
                    ChangeByteTurn(designKeyArr);
                    string designKey = ByteArrayTool.BytesToString(designKeyArr);


                    byte[] valueLengthArr = br.ReadBytes(2);
                    ChangeByteTurn(valueLengthArr);
                    int valueLength = BitConverter.ToInt16(valueLengthArr, 0);
                    byte[] clientValueArr = br.ReadBytes(valueLength);
                    ChangeByteTurn(clientValueArr);
                    string clientValue = ByteArrayTool.BytesToString(clientValueArr);

                    HandleProperties(serverKey.ToString(), clientValue);
                    HandleProperties(designKey, clientValue);
                }
            }


            // 读取完毕，关闭.
            br.Close();
            fs.Close();

            br = null;
            fs = null;
        }
        catch (Exception ex)
        {
            Console.WriteLine("BinaryReaderTool");
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
        }
        finally
        {
            if (br != null)
            {
                try
                {
                    br.Close();
                }
                catch
                {
                    // 最后关闭文件，无视 关闭是否会发生错误了.//
                }
            }

            if (fs != null)
            {
                try
                {
                    fs.Close();
                }
                catch
                {
                    // 最后关闭文件，无视 关闭是否会发生错误了.//
                }
            }
        }

        Console.WriteLine("读取二进制文件信息结束！");
    }


    /// <summary>
    /// 直接获取对应的字符串
    /// </summary>
    public string getSwfLangStr(string StrID)
    {
        LoadString();

        if (CheckProperties(StrID) == false) return StrID;

        return (string)GetProperties(StrID);
    }

    /// <summary>
    /// 将指定的String中的每个格式项替换为相应对象的值的文本等效项xxx{@0:xxx}xxx
    /// </summary>
    /// <param name="StrID">字符key</param>
    /// <param name="valArr">参数对象数组</param>
    public string getSwfLangStrVar(string StrID, params object[] valArr)
    {
        LoadString();

        if (CheckProperties(StrID) == false) return StrID;

        string strData = (string)GetProperties(StrID);

        int indexpre;
        int indexback;
        string strget;

        indexpre = strData.IndexOf("{");
        indexback = strData.IndexOf("}");

        //下一次搜索的起始偏移量,防止{@}嵌套时,造成死循环//
        int nextOffset = 0;

        int firstIndex;

        int strFlagPre;
        int strFlagBack;
        string strFlag;

        while (indexpre != -1 && indexback != -1)
        {
            strget = strData.Substring(indexpre, indexback - indexpre + 1);

            firstIndex = strData.IndexOf("@", nextOffset);
            string strNum = strData.Substring(firstIndex + 1, strData.IndexOf(":", firstIndex) - firstIndex - 1);
            int number = strNum == "" ? 0 : int.Parse(strNum);

            //处理填充字符串参数（如果有）//
            strFlagPre = strData.IndexOf("!#[", nextOffset) + 3;

            if (strFlagPre > 2)
            {
                //前缀{!#[PeerageRank_]@0:}
                strFlagBack = strData.IndexOf("]@", nextOffset);
                strFlag = strData.Substring(strFlagPre, strFlagBack - strFlagPre + 1);
                valArr[number] = getSwfLangStr(strFlag + valArr[number]);
            }

            string strreplace = valArr[number].ToString();

            strData = strData.Replace(strget, strreplace);

            nextOffset = indexpre + strreplace.Length;

            indexpre = strData.IndexOf("{", nextOffset);
            indexback = strData.IndexOf("}", nextOffset);
        }

        return strData;
    }

    /// <summary>
    /// xxx{0}xxx
    /// </summary>
    public string getSwfLangStrVarEx(string StrID, params object[] args)
    {
        LoadString();

        if (CheckProperties(StrID) == false) return StrID;

        string strData = (string)GetProperties(StrID);

        return String.Format(strData, args);
    }

    private void ChangeByteTurn(byte[] byteArr)
    {
        if (Is_Little_Endian)
        {
            Array.Reverse(byteArr);
        }
    }




}